package com.hdu.dwh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hdu.dwh.dtos.SubjectTableDto;
import com.hdu.dwh.dtos.TablePageDto;
import com.hdu.dwh.pojos.*;
import com.hdu.dwh.pojos.source_access_pojos.DataWarehouseTable;
import com.hdu.dwh.mapper.SubjectTableMapper;
import com.hdu.dwh.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdu.dwh.vos.*;
import com.hdu.dwh.constants.CommonConstants;
import com.hdu.dwh.constants.ParamConstants;
import com.hdu.dwh.enums.HttpStatusEnum;
import com.hdu.dwh.exception.CustomException;
import com.hdu.dwh.results.PageResponseResult;
import com.hdu.dwh.results.ResponseResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 主题数据表 服务实现类
 * </p>
 *
 * @author bobo
 * @since 2025-04-08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SubjectTableServiceImpl extends ServiceImpl<SubjectTableMapper, SubjectTable> implements ISubjectTableService {

    private final ISubjectDatabaseSourceService subjectDatabaseSourceService;
    private final ISubjectTableSourceService subjectTableSourceService;
    private final DataWarehouseTableService sourceTableService;
    private final DataWarehouseDatabaseService sourceDatabaseService;

    private final ISubjectDatabaseService subjectDatabaseService;
    private final DatabaseAllServiceImpl databaseAllService;

    private final SubjectTableMapper subjectTableMapper;

    /**
     * 新增主题数据表 要同步更新 主题数据库-源表 主题数据表-源表
     * @param subjectTableDto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult add(SubjectTableDto subjectTableDto) {
        if (subjectTableDto == null) {
            return ResponseResult.fail(CommonConstants.PARAM_IS_NULL);
        }
        // 检查参数
        if(!subjectTableDto.checkParam()){
            return ResponseResult.fail(CommonConstants.PARAM_IS_ERROR);
        }
        // 检查这个数据库下是否存在同表名的表
        if(existsTable(subjectTableDto.getDatabaseId(), subjectTableDto.getTableName())){
            return ResponseResult.fail(CommonConstants.DATAWAREHOUSE_TABLE_EXIST);
        }
        // 检查对应数据库是否存在
        if(!databaseAllService.existsById(subjectTableDto.getDatabaseId())){
            return ResponseResult.fail(CommonConstants.RECORD_NOT_EXIST);
        }
        // 检查源数据表是否存在
//        if(subjectTableDto.getHierarchy().equals(ParamConstants.DWS)){
//            if(!sourceTableService.existsByIds(subjectTableDto.getSourceTableIds())){
//                return ResponseResult.fail(CommonConstants.SOURCE_TABLE_NOT_EXIST);
//            }
//        } else {
//            if(!existsByIds(subjectTableDto.getSourceTableIds())){
//                return ResponseResult.fail(CommonConstants.SOURCE_TABLE_NOT_EXIST);
//            }
//        }
        // 保存主题数据表
        SubjectTable subjectTable = new SubjectTable();
        BeanUtils.copyProperties(subjectTableDto, subjectTable);
        if(!save(subjectTable)){
            return ResponseResult.fail(CommonConstants.ADD_FAILED);
        }
        // 获取源表信息 和源库信息 源表信息查对应表 源库信息查表对应库（去重）
        // 这里要区分源表来自 主题数据库 还是 源数据库 dws来自源数据库 ads来源主题数据库
        // 来自源数据库
//        List<SubjectTableSource> subjectTableSources = new ArrayList<>();
//        List<SubjectDatabaseSource> subjectDatabaseSources = new ArrayList<>();
//        if(Objects.equals(subjectTableDto.getHierarchy(), ParamConstants.DWS)){
//            // 查源表信息
//            List<SourceTable> sourceTables = sourceTableService.listByIds(subjectTableDto.getSourceTableIds());
//            if(sourceTables.size()!=subjectTableDto.getSourceTableIds().size()){
//                throw new CustomException(HttpStatusEnum.QUARY_ERROR);
//            }
//            for (SourceTable sourceTable : sourceTables) {
//                // 源表
//                SubjectTableSource subjectTableSource = new SubjectTableSource();
//                subjectTableSource.setSubjectTableId(subjectTable.getId())
//                        .setSourceTableId(sourceTable.getId())
//                        .setSourceTableName(sourceTable.getTableName());
//                subjectTableSources.add(subjectTableSource);
//            }
//            // 查源库信息
//            List<Long> sourceDatabaseIds = sourceTables.stream()
//                    .map(SourceTable::getDatabaseId)
//                    .distinct()
//                    .toList();
//            List<SourceDatabase> sourceDatabases = sourceDatabaseService.listByIds(sourceDatabaseIds);
//            if(sourceDatabases.size()!=sourceDatabaseIds.size()){
//                throw new CustomException(HttpStatusEnum.QUARY_ERROR);
//            }
//            for (SourceDatabase sourceDatabase : sourceDatabases) {
//                SubjectDatabaseSource subjectDatabaseSource = new SubjectDatabaseSource();
//                subjectDatabaseSource.setSubjectDatabaseId(subjectTable.getDatabaseId())
//                        .setSourceDatabaseId(sourceDatabase.getId())
//                        .setSourceDatabaseName(sourceDatabase.getDatabaseName())
//                        .setSourceType(sourceDatabase.getSourceType())
//                        .setDataType(sourceDatabase.getDataType());
//                subjectDatabaseSources.add(subjectDatabaseSource);
//            }
//        } // 来自主题数据库
//        else if (Objects.equals(subjectTableDto.getHierarchy(), ParamConstants.ADS)) {
//            LambdaQueryWrapper<SubjectTable> sourceDatabaseLambdaQueryWrapper = new LambdaQueryWrapper<SubjectTable>()
//                    .in(SubjectTable::getId, subjectTableDto.getSourceTableIds());
//            List<SubjectTable> sourceTables = list(sourceDatabaseLambdaQueryWrapper);
//            if(sourceTables.size()!=subjectTableDto.getSourceTableIds().size()){
//                throw new CustomException(HttpStatusEnum.QUARY_ERROR);
//            }
//            for (SubjectTable sourceTable : sourceTables) {
//                SubjectTableSource subjectTableSource = new SubjectTableSource();
//                subjectTableSource.setSubjectTableId(subjectTable.getId())
//                        .setSourceTableId(sourceTable.getId())
//                        .setSourceTableName(sourceTable.getTableName());
//                subjectTableSources.add(subjectTableSource);
//            }
//        }
//        // 保存源表信息
//        if(!subjectTableSourceService.saveBatch(subjectTableSources)){
//            throw new CustomException(HttpStatusEnum.INSERT_ERROR);
//        }
//        // 保存源库信息
//        if(!subjectDatabaseSources.isEmpty()&&!subjectDatabaseSourceService.saveBatch(subjectDatabaseSources)){
//            throw new CustomException(HttpStatusEnum.INSERT_ERROR);
//        }
        return ResponseResult.success(CommonConstants.ADD_SUCCESS);
    }

    /**
     * 判断源数据表是否存在
     * @param sourceTableIds
     * @return
     */
    private boolean existsByIds(List<Long> sourceTableIds) {
        LambdaQueryWrapper<DataWarehouseTable> queryWrapper = new LambdaQueryWrapper<DataWarehouseTable>()
                .in(DataWarehouseTable::getId, sourceTableIds);
        return sourceTableService.list(queryWrapper).size() == sourceTableIds.size();
    }

    /**
     * 判断是否存在同名表
     * @param databaseId
     * @param tableName
     * @return
     */
    private boolean existsTable(Long databaseId, String tableName) {
        LambdaQueryWrapper<SubjectTable> queryWrapper = new LambdaQueryWrapper<SubjectTable>()
                .eq(SubjectTable::getDatabaseId, databaseId)
                .eq(SubjectTable::getTableName, tableName);
        return exists(queryWrapper);
    }

    /**
     * 获取主题数据表详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult getDetilById(Long id) {
        if (id == null){
            return ResponseResult.fail(CommonConstants.PARAM_IS_NULL);
        }
        SubjectTable getById = getById(id);
        if (getById == null){
            return ResponseResult.fail(CommonConstants.RECORD_NOT_EXIST);
        }
        LambdaQueryWrapper<SubjectTableSource> wrapper = new LambdaQueryWrapper<SubjectTableSource>()
                .eq(SubjectTableSource::getSubjectTableId, id);
        List<SubjectTableSourceVo> sourceTables = subjectTableSourceService.list(wrapper)
                .stream().map(source -> {
                    SubjectTableSourceVo vo = new SubjectTableSourceVo();
                    BeanUtils.copyProperties(source, vo);
                    return vo;
                }).toList();
        SubjectTableVo subjectTableVo = new SubjectTableVo();
        BeanUtils.copyProperties(getById, subjectTableVo);
        subjectTableVo.setSourceTables(sourceTables);
        return ResponseResult.success(subjectTableVo);
    }

    /**
     * 查询主题数据表总数
     * @param hierarchy
     * @return
     */
    @Override
    public long countTablesByHierarchy(Integer hierarchy) {
        LambdaQueryWrapper<SubjectTable> queryWrapper = new LambdaQueryWrapper<SubjectTable>()
                .eq(SubjectTable::getHierarchy, hierarchy);
        return count(queryWrapper);
    }

    /**
     * 获取树形结构
     * @return
     */
    @Override
    public TreeVo getTreeVo() {
        // 把各层的表查出来 逐步封装Vo
        List<SubjectDatabase> subjectDatabases = subjectDatabaseService.list();
        List<SubjectTable> subjectTables = list();
        // 封装主题数据库
        List<DatabaseVo> subjectDatabasesVo = new ArrayList<>();
        for (SubjectDatabase subjectDatabase : subjectDatabases) {
            DatabaseVo databaseVo = new DatabaseVo();
            BeanUtils.copyProperties(subjectDatabase, databaseVo);
            List<HierarchyVo> hierarchyVos = new ArrayList<>();
            for (SubjectTable subjectTable : subjectTables) {
                if (Objects.equals(subjectTable.getDatabaseId(), subjectDatabase.getId())) {
                    // 查找或创建 HierarchyVo
                    HierarchyVo hierarchyVo = hierarchyVos.stream()
                            .filter(h -> Objects.equals(h.getHierarchy(), subjectTable.getHierarchy()))
                            .findFirst()
                            .orElseGet(() -> {
                                HierarchyVo newHierarchyVo = new HierarchyVo().setHierarchy(subjectTable.getHierarchy()).setTables(new ArrayList<>());
                                hierarchyVos.add(newHierarchyVo);
                                return newHierarchyVo;
                            });
                    // 创建 TableVo 并添加到 HierarchyVo 中
                    TableVo tableVo = new TableVo();
                    BeanUtils.copyProperties(subjectTable, tableVo);
                    hierarchyVo.getTables().add(tableVo);
                }
            }
            databaseVo.setHierarchys(hierarchyVos);
            subjectDatabasesVo.add(databaseVo);
        }
        if (subjectDatabasesVo.isEmpty()){
            return null;
        }
        return new TreeVo().setDatabaseType(ParamConstants.SUBJECT_DATABASE).setDatabases(subjectDatabasesVo);
    }




    /**
     * 获取主题数据表
     * @param databaseId
     * @param databaseName
     * @param hierarchy
     * @return
     */
    @Override
    public ResponseResult getTable(Long databaseId, String databaseName, Integer hierarchy) {
        List<TableVo> tables = subjectTableMapper.getTable(databaseId, databaseName, hierarchy);
        if(tables.isEmpty()){
            return ResponseResult.fail(CommonConstants.RECORD_NOT_EXIST);
        }
        return ResponseResult.success(tables);
    }

    @Override
    public ResponseResult tree() {
        TreeVo treeVo = getTreeVo();
        if(treeVo==null){
            return ResponseResult.fail(CommonConstants.RECORD_NOT_EXIST);
        }
        return ResponseResult.success(treeVo.getDatabases());
    }

    /**
     * 根据数据库id删除主题数据表
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean deleteByDatabaseId(Long id) {
        if( id != null){
            // 查表id
            LambdaQueryWrapper<SubjectTable> queryWrapper = new LambdaQueryWrapper<SubjectTable>()
                    .select(SubjectTable::getId)
                    .eq(SubjectTable::getDatabaseId, id);
            List<Long> tableIds = listObjs(queryWrapper);
            if(tableIds.isEmpty()){
                return true;
            }
            // 删表
            if(!removeBatchByIds(tableIds)){
                return false;
            }
            // 删表源
            if(!subjectTableSourceService.deleteBySubjectTableIds(tableIds)){
                throw new CustomException(HttpStatusEnum.DELETE_FAILED);
            }
        }
        return true;
    }

    @Override
    @Transactional
    public ResponseResult deleteById(Long id) {
        if (id == null){
            return ResponseResult.fail(CommonConstants.PARAM_IS_NULL);
        }
        if(!removeById(id)){
            return ResponseResult.fail(CommonConstants.DELETE_FAILED);
        }
        // 删表源
        if(!subjectTableSourceService.deleteBySubjectTableId(id)){
            throw new CustomException(HttpStatusEnum.DELETE_FAILED);
        }
        return ResponseResult.success(CommonConstants.DELETE_SUCCESS);
    }


    /**
     * 查询详细信息(分页)
     * @param tablePageDto
     * @return
     */
    @Override
    public ResponseResult detilPage(TablePageDto tablePageDto) {
        if(tablePageDto == null){
            return ResponseResult.fail(CommonConstants.PARAM_IS_NULL);
        }
        tablePageDto.checkParam();
        IPage<SubjectTable> page = Page.of(tablePageDto.getPage(), tablePageDto.getSize());
        LambdaQueryWrapper<SubjectTable> queryWrapper = new LambdaQueryWrapper<>();
        // 因为需要根据databaseName查 所以要先查这个信息 还要分页
        // 这里构造查询条件
        if(tablePageDto.getDatabaseName()!= null){
            Long databaseId = databaseAllService.getIdByDatabaseName(tablePageDto.getDatabaseName());
            if(databaseId == null || !databaseId.equals(tablePageDto.getDatabaseId())){
                return ResponseResult.fail(CommonConstants.PARAM_IS_ERROR);
            }
            queryWrapper.eq(SubjectTable::getDatabaseId, databaseId);
        }else if(tablePageDto.getDatabaseId() != null){
            queryWrapper.eq(SubjectTable::getDatabaseId, tablePageDto.getDatabaseId());
        }
        if(tablePageDto.getHierarchy() != null){
            queryWrapper.eq(SubjectTable::getHierarchy, tablePageDto.getHierarchy());
        }
        // 查询
        if(!queryWrapper.getExpression().getNormal().isEmpty()){
            page = page(page, queryWrapper);
        }
        else{
            page = page(page);
        }
        // 没查到信息
        if(page.getRecords().isEmpty()){
            return ResponseResult.fail(CommonConstants.RECORD_NOT_EXIST);
        }
        List<TableDetilVo> tableDetilVos = databaseAllService.createTableDetilVoListForSubject(page.getRecords());
        return PageResponseResult.success((int) page.getCurrent(), (int) page.getPages(), (int) page.getSize(), (int) page.getTotal() ,tableDetilVos);
    }
}
